﻿using Agile.Infra.Core.Agile;
using Agile.Infra.Core.Exceptions;
using Agile.Infra.IdGenerator.Yitter;
using Agile.Shared;

namespace Agile.Service.Admin.WebApi.Controllers
{
    /// <summary>
    /// 文件上传服务接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FilesController : AgileControllerBase
    {
        public const string direName = "UploadFile";
        private readonly IWebHostEnvironment _webHostEnvironment;
        private readonly ISysAttachService _sysAttachService;
        public FilesController(IWebHostEnvironment webHostEnvironment, ISysAttachService sysAttachService)
        {
            this._webHostEnvironment = webHostEnvironment;
            this._sysAttachService = sysAttachService;
        }

        [HttpPost]
        public async Task<UploadResult> UploadFile(string attachType)
        {
            var files = Request.Form.Files;

            if (files.Count < 1)
            {
                throw new BusinessException("没有选择上传文件");
            }
            var rootPath = _webHostEnvironment.WebRootPath;
            var resList = new List<UploadResult>();
            var loginUser = this.GetService<UserContext>();

            if (rootPath.IsNullOrWhiteSpace())
                rootPath = Appsettings.App<string>("wwwroot");

            var attachSupport = _sysAttachService.GetFileSupport(attachType);

            foreach (var formFile in files)
            {
                if (formFile != null && formFile.Length > 0)
                {
                    //文件后缀
                    var fileExtension = Path.GetExtension(formFile.FileName).ToLower();

                    if (attachSupport.SupportExtension != "*" && attachSupport.SupportExtension.IndexOf(fileExtension.ToLower(), StringComparison.Ordinal) <= -1)
                    {
                        throw new BusinessException($"请上传{attachSupport.SupportExtension}格式的文件");
                    }

                    //判断文件大小     
                    if (formFile.Length > attachSupport.SupportFileSize)
                    {
                        throw new BusinessException($"上传的文件不能大于{(attachSupport.SupportFileSize / 1024 / 1024)}M");
                    }

                    string newFileName = Guid.NewGuid() + fileExtension;
                    string saveDir = DateTime.Now.ToString("yyyyMM");
                    string savePath = Path.Combine(rootPath, direName, attachType, saveDir);

                    if (!Directory.Exists(savePath))
                    {
                        Directory.CreateDirectory(savePath);
                    }

                    using (var stream = System.IO.File.Create(Path.Combine(savePath, newFileName)))
                    {
                        await formFile.CopyToAsync(stream);

                        resList.Add(new UploadResult()
                        {
                            AttachID = IdGenerater.GetNextId(),
                            SaveFileName = newFileName,
                            SaveFilePath = Path.Combine("/", direName, attachType, saveDir, newFileName),
                            UploadFileName = formFile.FileName,
                            FileExtension = fileExtension,
                        });
                    }

                    var attachList = new List<SysAttachModel>();
                    foreach (var item in resList)
                    {
                        attachList.Add(new SysAttachModel
                        {
                            AttachID = item.AttachID,
                            AttachType = attachType,
                            CreateID = loginUser?.UserID ?? 0,
                            CreateTime = DateTime.Now,
                            FileName = item.UploadFileName,
                            FilePath = item.SaveFilePath,
                            FileSize = (int)formFile.Length,
                            Extension = fileExtension
                        });

                        item.Url = item.SaveFilePath;
                        item.Code = item.AttachID;
                        item.Message = item.UploadFileName;
                    }

                    await this.GetService<ISysAttachService>().AddAsync(attachList);
                }
            }
            return resList[0];
        }

        [HttpPost]
        public async Task<ResponseResult<UploadResult>> Upload(string attachType)
        {
            var files = Request.Form.Files;

            if (files.Count < 1)
            {
                throw new BusinessException("没有选择上传文件");
            }
            var rootPath = _webHostEnvironment.WebRootPath;
            var resList = new List<UploadResult>();
            var loginUser = this.GetService<UserContext>();

            if (rootPath.IsNullOrWhiteSpace())
                rootPath = Appsettings.App<string>("wwwroot");

            if (rootPath.IsNullOrWhiteSpace())
                rootPath = Appsettings.App<string>("wwwroot");

            var attachSupport = _sysAttachService.GetFileSupport(attachType);

            foreach (var formFile in files)
            {
                if (formFile != null && formFile.Length > 0)
                {
                    //文件后缀
                    var fileExtension = Path.GetExtension(formFile.FileName).ToLower();

                    if (attachSupport.SupportExtension != "*" && attachSupport.SupportExtension.IndexOf(fileExtension.ToLower(), StringComparison.Ordinal) <= -1)
                    {
                        throw new BusinessException($"请上传{attachSupport.SupportExtension}格式的文件");
                    }

                    //判断文件大小     
                    if (formFile.Length > attachSupport.SupportFileSize)
                    {
                        throw new BusinessException($"上传的文件不能大于{(attachSupport.SupportFileSize / 1024 / 1024)}M");
                    }

                    string newFileName = Guid.NewGuid() + fileExtension;
                    string saveDir = DateTime.Now.ToString("yyyyMM");
                    string savePath = Path.Combine(rootPath, direName, attachType, saveDir);

                    if (!Directory.Exists(savePath))
                    {
                        Directory.CreateDirectory(savePath);
                    }

                    using (var stream = System.IO.File.Create(Path.Combine(savePath, newFileName)))
                    {
                        await formFile.CopyToAsync(stream);

                        resList.Add(new UploadResult()
                        {
                            AttachID = IdGenerater.GetNextId(),
                            SaveFileName = newFileName,
                            SaveFilePath = Path.Combine("/", direName, attachType, saveDir, newFileName),
                            UploadFileName = formFile.FileName,
                            FileExtension = fileExtension,
                        });
                    }

                    var attachList = new List<SysAttachModel>();
                    foreach (var item in resList)
                    {
                        attachList.Add(new SysAttachModel
                        {
                            AttachID = item.AttachID,
                            AttachType = attachType,
                            CreateID = loginUser?.UserID ?? 0,
                            CreateTime = DateTime.Now,
                            FileName = item.UploadFileName,
                            FilePath = item.SaveFilePath,
                            FileSize = (int)formFile.Length,
                            Extension = fileExtension
                        });

                        item.Url = item.SaveFilePath;
                        item.Code = item.AttachID;
                        item.Message = item.UploadFileName;
                    }

                    await this.GetService<ISysAttachService>().AddAsync(attachList);
                }
            }
            return Result(resList[0]);
        }

    }


    public class UploadResult
    {
        public string Message { get; set; }
        public long Code { get; set; }
        public string Url { get; set; }
        public long AttachID { get; set; }
        public string SaveFileName { get; set; }
        public string UploadFileName { get; set; }
        public string SaveFilePath { get; set; }
        public string FileExtension { get; set; }
    }

    public enum UploadFileType
    {
        File,
        Image
    }
}